import Layout from '../../components/docs-layout';
import toast from 'react-hot-toast';

export const meta = {
  title: 'toast() API',
};

# `toast()` API

Call it to create a toast from anywhere, even outside React. Make sure you add the [`<Toaster/>`](/docs/toaster) component to your app first.

## Available toast options

You can provide `ToastOptions` as the second argument. They will overwrite all options received from [`<Toaster/>`](/docs/toaster).

```js
toast('Hello World', {
  duration: 4000,
  position: 'top-center',

  // Styling
  style: {},
  className: '',

  // Custom Icon
  icon: '👏',

  // Change colors of success/error/loading icon
  iconTheme: {
    primary: '#000',
    secondary: '#fff',
  },

  // Aria
  ariaProps: {
    role: 'status',
    'aria-live': 'polite',
  },

  // Additional Configuration
  removeDelay: 1000,

  // Toaster instance
  toasterId: 'default',
});
```

## Creating a toast

### Blank

```js
toast('Hello World');
```

The most basic variant. It does not have an icon by default, but you can provide one via the options. If you don't want any default styles, use `toast.custom()` instead.

### Success

```js
toast.success('Successfully created!');
```

Creates a notification with an animated checkmark. It can be themed with the `iconTheme` option.

### Error

```js
toast.error('This is an error!');
```

Creates a notification with an animated error icon. It can be themed with the `iconTheme` option.

### Custom (JSX)

```js
toast.custom(<div>Hello World</div>);
```

Creates a custom notification with JSX without default styles.

### Loading

```js
toast.loading('Waiting...');
```

This will create a loading notification. Most likely, you want to update it afterwards. For a friendly alternative, check out `toast.promise()`, which takes care of that automatically.

### Promise

This shorthand is useful for mapping a promise to a toast. It will update automatically when the promise resolves or fails.

#### Simple Usage

```js
const myPromise = fetchData();

toast.promise(myPromise, {
  loading: 'Loading',
  success: 'Got the data',
  error: 'Error when fetching',
});
```

It's recommend to add min-width to your `toast.promise()` calls to **prevent jumps** from different message lengths.

#### Advanced

You can provide a function to the success/error messages to incorporate the result/error of the promise. The third argument are `toastOptions` similiar to [`<Toaster />`](/docs/toaster)

```js
toast.promise(
  myPromise,
  {
    loading: 'Loading',
    success: (data) => `Successfully saved ${data.name}`,
    error: (err) => `This just happened: ${err.toString()}`,
  },
  {
    style: {
      minWidth: '250px',
    },
    success: {
      duration: 5000,
      icon: '🔥',
    },
  }
);
```

#### Using an Async Function

You can also provide a function that returns a promise, which will be called automatically.

```js
toast.promise(
  async () => {
    const { id } = await fetchData1();
    await fetchData2(id);
  },
  {
    loading: 'Loading',
    success: 'Got the data',
    error: 'Error when fetching',
  }
);
```

## Default durations

Every type has its own duration. You can overwrite them `duration` with the toast options. This can be done per toast options or globally by the [`<Toaster/>`](/docs/toaster).

| type      | duration |
| --------- | -------- |
| `blank`   | 4000     |
| `error`   | 4000     |
| `success` | 2000     |
| `custom`  | 4000     |
| `loading` | Infinity |

### Dismiss toast programmatically

You can manually dismiss a notification with `toast.dismiss`. Be aware that it triggers the exit animation and does not remove the Toast instantly. Toasts will auto-remove after 1 second by default.

#### Dismiss a single toast

```js
const toastId = toast.loading('Loading...');

// ...

toast.dismiss(toastId);
```

You can dismiss all toasts at once, by leaving out the `toastId`.

#### Dismiss all toasts at once

```js
toast.dismiss();
```

To remove toasts instantly without any animations, use `toast.remove`.

#### Configure remove delay

```js
toast.success('Successfully created!', { removeDelay: 500 });
```

By default, the remove operation is delayed by 1000ms. This is how long a toast should be kept in the DOM after being dismissed. It is used to play the exit animation. This duration (number in milliseconds) can be configured when calling the toast.

Or, for all toasts, using the Toaster like so:

```js
<Toaster
  toastOptions={{
    removeDelay: 500,
  }}
/>
```

#### Remove toasts instantly

```js
toast.remove(toastId);

// or

toast.remove();
```

### Update an existing toast

Each toast call returns a unique id. Use in the toast options to update the existing toast.

```js
const toastId = toast.loading('Loading...');

// ...

toast.success('This worked', {
  id: toastId,
});
```

### Prevent duplicate toasts

To prevent duplicates of the same kind, you can provide a unique permanent id.

```js
toast.success('Copied to clipboard!', {
  id: 'clipboard',
});
```

### Render JSX custom content

You can provide a React component instead of text. If you don't want any default styles use `toast.custom()` instead.

```jsx
toast(
  <span>
    Custom and <b>bold</b>
  </span>,
  {
    icon: <Icon />,
  }
);
```

You can also supply a function that receives the `Toast` as an argument, giving you access to all properties. This allows you to access the toast id, which can be used to add a dismiss button.

```jsx
toast(
  (t) => (
    <span>
      Custom and <b>bold</b>
      <button onClick={() => toast.dismiss(t.id)}>Dismiss</button>
    </span>
  ),
  {
    icon: <Icon />,
  }
);
```

export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
